home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / ddx / mfb / RCS / mfbgc.c,v < prev    next >
Encoding:
Text File  |  1991-02-28  |  29.2 KB  |  1,352 lines

  1. head     1.2;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.2
  10. date     91.02.27.23.32.23;  author kupfer;  state Exp;
  11. branches ;
  12. next     1.1;
  13.  
  14. 1.1
  15. date     90.02.14.19.58.05;  author tve;  state Exp;
  16. branches ;
  17. next     ;
  18.  
  19.  
  20. desc
  21. @Original X11R4 distribution
  22. @
  23.  
  24.  
  25. 1.2
  26. log
  27. @Patch #7 from MIT.
  28. @
  29. text
  30. @/***********************************************************
  31. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  32. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  33.  
  34.                         All Rights Reserved
  35.  
  36. Permission to use, copy, modify, and distribute this software and its 
  37. documentation for any purpose and without fee is hereby granted, 
  38. provided that the above copyright notice appear in all copies and that
  39. both that copyright notice and this permission notice appear in 
  40. supporting documentation, and that the names of Digital or MIT not be
  41. used in advertising or publicity pertaining to distribution of the
  42. software without specific, written prior permission.  
  43.  
  44. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  45. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  46. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  47. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  48. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  49. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  50. SOFTWARE.
  51.  
  52. ******************************************************************/
  53. /* $XConsortium: mfbgc.c,v 5.19 90/03/20 14:48:59 rws Exp $ */
  54. #include "X.h"
  55. #include "Xmd.h"
  56. #include "Xproto.h"
  57. #include "dixfontstr.h"
  58. #include "fontstruct.h"
  59. #include "gcstruct.h"
  60. #include "windowstr.h"
  61. #include "pixmapstr.h"
  62. #include "scrnintstr.h"
  63. #include "region.h"
  64.  
  65. #include "mfb.h"
  66. #include "mistruct.h"
  67.  
  68. #include "maskbits.h"
  69.  
  70. static void mfbDestroyOps();
  71.  
  72. static GCFuncs    mfbFuncs = {
  73.     mfbValidateGC,
  74.     mfbChangeGC,
  75.     mfbCopyGC,
  76.     mfbDestroyGC,
  77.     mfbChangeClip,
  78.     mfbDestroyClip,
  79.     mfbCopyClip,
  80. };
  81.  
  82. static GCOps    whiteTECopyOps = {
  83.     mfbWhiteSolidFS,
  84.     mfbSetSpans,
  85.     mfbPutImage,
  86.     mfbCopyArea,
  87.     mfbCopyPlane,
  88.     mfbPolyPoint,
  89.     mfbLineSS,
  90.     mfbSegmentSS,
  91.     miPolyRectangle,
  92.     mfbZeroPolyArcSS,
  93.     miFillPolygon,
  94.     mfbPolyFillRect,
  95.     mfbPolyFillArcSolid,
  96.     miPolyText8,
  97.     miPolyText16,
  98.     miImageText8,
  99.     miImageText16,
  100.     mfbTEGlyphBltWhite,
  101.     mfbPolyGlyphBltWhite,
  102.     mfbSolidPP,
  103.     NULL,
  104. };
  105.  
  106. static GCOps    blackTECopyOps = {
  107.     mfbBlackSolidFS,
  108.     mfbSetSpans,
  109.     mfbPutImage,
  110.     mfbCopyArea,
  111.     mfbCopyPlane,
  112.     mfbPolyPoint,
  113.     mfbLineSS,
  114.     mfbSegmentSS,
  115.     miPolyRectangle,
  116.     mfbZeroPolyArcSS,
  117.     miFillPolygon,
  118.     mfbPolyFillRect,
  119.     mfbPolyFillArcSolid,
  120.     miPolyText8,
  121.     miPolyText16,
  122.     miImageText8,
  123.     miImageText16,
  124.     mfbTEGlyphBltBlack,
  125.     mfbPolyGlyphBltBlack,
  126.     mfbSolidPP,
  127.     NULL,
  128. };
  129.  
  130. static GCOps    whiteTEInvertOps = {
  131.     mfbInvertSolidFS,
  132.     mfbSetSpans,
  133.     mfbPutImage,
  134.     mfbCopyArea,
  135.     mfbCopyPlane,
  136.     mfbPolyPoint,
  137.     mfbLineSS,
  138.     mfbSegmentSS,
  139.     miPolyRectangle,
  140.     miZeroPolyArc,
  141.     miFillPolygon,
  142.     mfbPolyFillRect,
  143.     mfbPolyFillArcSolid,
  144.     miPolyText8,
  145.     miPolyText16,
  146.     miImageText8,
  147.     miImageText16,
  148.     mfbTEGlyphBltWhite,
  149.     mfbPolyGlyphBltInvert,
  150.     mfbSolidPP,
  151.     NULL,
  152. };
  153.  
  154. static GCOps    blackTEInvertOps = {
  155.     mfbInvertSolidFS,
  156.     mfbSetSpans,
  157.     mfbPutImage,
  158.     mfbCopyArea,
  159.     mfbCopyPlane,
  160.     mfbPolyPoint,
  161.     mfbLineSS,
  162.     mfbSegmentSS,
  163.     miPolyRectangle,
  164.     miZeroPolyArc,
  165.     miFillPolygon,
  166.     mfbPolyFillRect,
  167.     mfbPolyFillArcSolid,
  168.     miPolyText8,
  169.     miPolyText16,
  170.     miImageText8,
  171.     miImageText16,
  172.     mfbTEGlyphBltBlack,
  173.     mfbPolyGlyphBltInvert,
  174.     mfbSolidPP,
  175.     NULL,
  176. };
  177.  
  178. static GCOps    whiteCopyOps = {
  179.     mfbWhiteSolidFS,
  180.     mfbSetSpans,
  181.     mfbPutImage,
  182.     mfbCopyArea,
  183.     mfbCopyPlane,
  184.     mfbPolyPoint,
  185.     mfbLineSS,
  186.     mfbSegmentSS,
  187.     miPolyRectangle,
  188.     mfbZeroPolyArcSS,
  189.     miFillPolygon,
  190.     mfbPolyFillRect,
  191.     mfbPolyFillArcSolid,
  192.     miPolyText8,
  193.     miPolyText16,
  194.     miImageText8,
  195.     miImageText16,
  196.     mfbImageGlyphBltWhite,
  197.     mfbPolyGlyphBltWhite,
  198.     mfbSolidPP,
  199.     NULL,
  200. };
  201.  
  202. static GCOps    blackCopyOps = {
  203.     mfbBlackSolidFS,
  204.     mfbSetSpans,
  205.     mfbPutImage,
  206.     mfbCopyArea,
  207.     mfbCopyPlane,
  208.     mfbPolyPoint,
  209.     mfbLineSS,
  210.     mfbSegmentSS,
  211.     miPolyRectangle,
  212.     mfbZeroPolyArcSS,
  213.     miFillPolygon,
  214.     mfbPolyFillRect,
  215.     mfbPolyFillArcSolid,
  216.     miPolyText8,
  217.     miPolyText16,
  218.     miImageText8,
  219.     miImageText16,
  220.     mfbImageGlyphBltBlack,
  221.     mfbPolyGlyphBltBlack,
  222.     mfbSolidPP,
  223.     NULL,
  224. };
  225.  
  226. static GCOps    whiteInvertOps = {
  227.     mfbInvertSolidFS,
  228.     mfbSetSpans,
  229.     mfbPutImage,
  230.     mfbCopyArea,
  231.     mfbCopyPlane,
  232.     mfbPolyPoint,
  233.     mfbLineSS,
  234.     mfbSegmentSS,
  235.     miPolyRectangle,
  236.     miZeroPolyArc,
  237.     miFillPolygon,
  238.     mfbPolyFillRect,
  239.     mfbPolyFillArcSolid,
  240.     miPolyText8,
  241.     miPolyText16,
  242.     miImageText8,
  243.     miImageText16,
  244.     mfbImageGlyphBltWhite,
  245.     mfbPolyGlyphBltInvert,
  246.     mfbSolidPP,
  247.     NULL,
  248. };
  249.  
  250. static GCOps    blackInvertOps = {
  251.     mfbInvertSolidFS,
  252.     mfbSetSpans,
  253.     mfbPutImage,
  254.     mfbCopyArea,
  255.     mfbCopyPlane,
  256.     mfbPolyPoint,
  257.     mfbLineSS,
  258.     mfbSegmentSS,
  259.     miPolyRectangle,
  260.     miZeroPolyArc,
  261.     miFillPolygon,
  262.     mfbPolyFillRect,
  263.     mfbPolyFillArcSolid,
  264.     miPolyText8,
  265.     miPolyText16,
  266.     miImageText8,
  267.     miImageText16,
  268.     mfbImageGlyphBltBlack,
  269.     mfbPolyGlyphBltInvert,
  270.     mfbSolidPP,
  271.     NULL,
  272. };
  273.  
  274. static GCOps    whiteWhiteCopyOps = {
  275.     mfbWhiteSolidFS,
  276.     mfbSetSpans,
  277.     mfbPutImage,
  278.     mfbCopyArea,
  279.     mfbCopyPlane,
  280.     mfbPolyPoint,
  281.     mfbLineSS,
  282.     mfbSegmentSS,
  283.     miPolyRectangle,
  284.     mfbZeroPolyArcSS,
  285.     miFillPolygon,
  286.     mfbPolyFillRect,
  287.     mfbPolyFillArcSolid,
  288.     miPolyText8,
  289.     miPolyText16,
  290.     miImageText8,
  291.     miImageText16,
  292.     miImageGlyphBlt,
  293.     mfbPolyGlyphBltWhite,
  294.     mfbSolidPP,
  295.     NULL,
  296. };
  297.  
  298. static GCOps    blackBlackCopyOps = {
  299.     mfbBlackSolidFS,
  300.     mfbSetSpans,
  301.     mfbPutImage,
  302.     mfbCopyArea,
  303.     mfbCopyPlane,
  304.     mfbPolyPoint,
  305.     mfbLineSS,
  306.     mfbSegmentSS,
  307.     miPolyRectangle,
  308.     mfbZeroPolyArcSS,
  309.     miFillPolygon,
  310.     mfbPolyFillRect,
  311.     mfbPolyFillArcSolid,
  312.     miPolyText8,
  313.     miPolyText16,
  314.     miImageText8,
  315.     miImageText16,
  316.     miImageGlyphBlt,
  317.     mfbPolyGlyphBltBlack,
  318.     mfbSolidPP,
  319.     NULL,
  320. };
  321.  
  322. static GCOps    fgEqBgInvertOps = {
  323.     mfbInvertSolidFS,
  324.     mfbSetSpans,
  325.     mfbPutImage,
  326.     mfbCopyArea,
  327.     mfbCopyPlane,
  328.     mfbPolyPoint,
  329.     mfbLineSS,
  330.     mfbSegmentSS,
  331.     miPolyRectangle,
  332.     miZeroPolyArc,
  333.     miFillPolygon,
  334.     mfbPolyFillRect,
  335.     mfbPolyFillArcSolid,
  336.     miPolyText8,
  337.     miPolyText16,
  338.     miImageText8,
  339.     miImageText16,
  340.     miImageGlyphBlt,
  341.     mfbPolyGlyphBltInvert,
  342.     mfbSolidPP,
  343.     NULL,
  344. };
  345.  
  346. struct commonOps {
  347.     int            fg, bg;
  348.     int            rrop;
  349.     int            terminalFont;
  350.     GCOps        *ops;
  351.     void        (*fillArea)();
  352. };
  353.  
  354. static struct commonOps mfbCommonOps[] = {
  355.     { 1, 0, RROP_WHITE, 1, &whiteTECopyOps, mfbSolidWhiteArea },
  356.     { 0, 1, RROP_BLACK, 1, &blackTECopyOps, mfbSolidBlackArea },
  357.     { 1, 0, RROP_INVERT, 1, &whiteTEInvertOps, mfbSolidInvertArea },
  358.     { 0, 1, RROP_INVERT, 1, &blackTEInvertOps, mfbSolidInvertArea },
  359.     { 1, 0, RROP_WHITE, 0, &whiteCopyOps, mfbSolidWhiteArea },
  360.     { 0, 1, RROP_BLACK, 0, &blackCopyOps, mfbSolidBlackArea },
  361.     { 1, 0, RROP_INVERT, 0, &whiteInvertOps, mfbSolidInvertArea },
  362.     { 0, 1, RROP_INVERT, 0, &blackInvertOps, mfbSolidInvertArea },
  363.     { 1, 1, RROP_WHITE, 0, &whiteWhiteCopyOps, mfbSolidWhiteArea },
  364.     { 0, 0, RROP_BLACK, 0, &blackBlackCopyOps, mfbSolidBlackArea },
  365.     { 1, 1, RROP_INVERT, 0, &fgEqBgInvertOps, mfbSolidInvertArea },
  366.     { 0, 0, RROP_INVERT, 0, &fgEqBgInvertOps, mfbSolidInvertArea },
  367. };
  368.  
  369. #define numberCommonOps    (sizeof (mfbCommonOps) / sizeof (mfbCommonOps[0]))
  370.  
  371. static GCOps *
  372. matchCommon (pGC)
  373.     GCPtr   pGC;
  374. {
  375.     int    i;
  376.     struct commonOps    *cop;
  377.     mfbPrivGC        *priv;
  378.  
  379.     if (pGC->lineWidth != 0)
  380.     return 0;
  381.     if (pGC->lineStyle != LineSolid)
  382.     return 0;
  383.     if (pGC->fillStyle != FillSolid)
  384.     return 0;
  385.     if (!pGC->font ||
  386.         pGC->font->pFI->maxbounds.metrics.rightSideBearing -
  387.     pGC->font->pFI->minbounds.metrics.leftSideBearing > 32)
  388.     return 0;
  389.     priv = (mfbPrivGC *) pGC->devPrivates[mfbGCPrivateIndex].ptr;
  390.     for (i = 0; i < numberCommonOps; i++) {
  391.     cop = &mfbCommonOps[i];
  392.     if (pGC->fgPixel != cop->fg)
  393.         continue;
  394.     if (pGC->bgPixel != cop->bg)
  395.         continue;
  396.     if (priv->rop != cop->rrop)
  397.         continue;
  398.     if (cop->terminalFont && !pGC->font->pFI->terminalFont)
  399.         continue;
  400.     priv->FillArea = cop->fillArea;
  401.     return cop->ops;
  402.     }
  403.     return 0;
  404. }
  405.  
  406. Bool
  407. mfbCreateGC(pGC)
  408.     register GCPtr pGC;
  409. {
  410.     mfbPrivGC     *pPriv;
  411.  
  412.     pGC->clientClip = NULL;
  413.     pGC->clientClipType = CT_NONE;
  414.     
  415.     /* some of the output primitives aren't really necessary, since
  416.        they will be filled in ValidateGC because of dix/CreateGC()
  417.        setting all the change bits.  Others are necessary because although
  418.        they depend on being a monochrome frame buffer, they don't change 
  419.     */
  420.  
  421.     pGC->ops = &whiteCopyOps;
  422.     pGC->funcs = &mfbFuncs;
  423.  
  424.     /* mfb wants to translate before scan convesion */
  425.     pGC->miTranslate = 1;
  426.  
  427.     pPriv = (mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr);
  428.     pPriv->rop = mfbReduceRop(pGC->alu, pGC->fgPixel);
  429.     pPriv->fExpose = TRUE;
  430.     pPriv->pRotatedPixmap = NullPixmap;
  431.     pPriv->freeCompClip = FALSE;
  432.     pPriv->FillArea = mfbSolidInvertArea;
  433.     return TRUE;
  434. }
  435.  
  436. /*ARGSUSED*/
  437. void
  438. mfbChangeGC(pGC, mask)
  439.     GC        *pGC;
  440.     BITS32  mask;
  441. {
  442.     return;
  443. }
  444.  
  445. /*ARGSUSED*/
  446. void
  447. mfbCopyGC (pGCSrc, changes, pGCDst)
  448.     GCPtr    pGCSrc;
  449.     Mask     changes;
  450.     GCPtr    pGCDst;
  451. {
  452.     return;
  453. }
  454.  
  455. void
  456. mfbDestroyGC(pGC)
  457.     GC             *pGC;
  458. {
  459.     mfbPrivGC *pPriv;
  460.  
  461.     pPriv = (mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr);
  462.     if (pPriv->pRotatedPixmap)
  463.     mfbDestroyPixmap(pPriv->pRotatedPixmap);
  464.     if (pPriv->freeCompClip)
  465.     (*pGC->pScreen->RegionDestroy)(pPriv->pCompositeClip);
  466.     mfbDestroyOps (pGC->ops);
  467. }
  468.  
  469. /*
  470.  * create a private op array for a gc
  471.  */
  472.  
  473. static GCOps *
  474. mfbCreateOps (prototype)
  475.     GCOps    *prototype;
  476. {
  477.     GCOps    *ret;
  478.     extern Bool    Must_have_memory;
  479.  
  480.     /* XXX */ Must_have_memory = TRUE;
  481.     ret = (GCOps *) xalloc (sizeof *ret);
  482.     /* XXX */ Must_have_memory = FALSE;
  483.     if (!ret)
  484.     return 0;
  485.     *ret = *prototype;
  486.     ret->devPrivate.val = 1;
  487.     return ret;
  488. }
  489.  
  490. static void
  491. mfbDestroyOps (ops)
  492.     GCOps   *ops;
  493. {
  494.     if (ops->devPrivate.val)
  495.     xfree (ops);
  496. }
  497.  
  498. /* Clipping conventions
  499.     if the drawable is a window
  500.         CT_REGION ==> pCompositeClip really is the composite
  501.         CT_other ==> pCompositeClip is the window clip region
  502.     if the drawable is a pixmap
  503.         CT_REGION ==> pCompositeClip is the translated client region
  504.         clipped to the pixmap boundary
  505.         CT_other ==> pCompositeClip is the pixmap bounding box
  506. */
  507.  
  508. /*ARGSUSED*/
  509. void
  510. mfbValidateGC(pGC, changes, pDrawable)
  511.     register GCPtr     pGC;
  512.     Mask         changes;
  513.     DrawablePtr     pDrawable;
  514. {
  515.     register mfbPrivGCPtr    devPriv;
  516.     WindowPtr pWin;
  517.     int mask;            /* stateChanges */
  518.     int index;            /* used for stepping through bitfields */
  519.     int    xrot, yrot;        /* rotations for tile and stipple pattern */
  520.     int rrop;            /* reduced rasterop */
  521.                 /* flags for changing the proc vector 
  522.                    and updating things in devPriv
  523.                 */
  524.     int new_rotate, new_rrop,  new_line, new_text, new_fill;
  525.     DDXPointRec    oldOrg;        /* origin of thing GC was last used with */
  526.  
  527.     oldOrg = pGC->lastWinOrg;
  528.  
  529.     pGC->lastWinOrg.x = pDrawable->x;
  530.     pGC->lastWinOrg.y = pDrawable->y;
  531.     if (pDrawable->type == DRAWABLE_WINDOW)
  532.     pWin = (WindowPtr)pDrawable;
  533.     else
  534.     pWin = (WindowPtr)NULL;
  535.  
  536.     /* we need to re-rotate the tile if the previous window/pixmap
  537.        origin (oldOrg) differs from the new window/pixmap origin
  538.        (pGC->lastWinOrg)
  539.     */
  540.     new_rotate = (oldOrg.x != pGC->lastWinOrg.x) ||
  541.          (oldOrg.y != pGC->lastWinOrg.y);
  542.  
  543.     devPriv = ((mfbPrivGCPtr) (pGC->devPrivates[mfbGCPrivateIndex].ptr));
  544.  
  545.     /*
  546.     if the client clip is different or moved OR
  547.     the subwindowMode has changed OR
  548.     the window's clip has changed since the last validation
  549.     we need to recompute the composite clip
  550.     */
  551.     if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) ||
  552.     (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
  553.        )
  554.     {
  555.     ScreenPtr pScreen = pGC->pScreen;
  556.  
  557.     if (pWin)
  558.     {
  559.         Bool freeTmpClip, freeCompClip;
  560.         RegionPtr pregWin;        /* clip for this window, without
  561.                        client clip */
  562.  
  563.         if (pGC->subWindowMode == IncludeInferiors)
  564.         {
  565.             pregWin = NotClippedByChildren(pWin);
  566.         freeTmpClip = TRUE;
  567.         }
  568.         else
  569.         {
  570.             pregWin = &pWin->clipList;
  571.         freeTmpClip = FALSE;
  572.         }
  573.         freeCompClip = devPriv->freeCompClip;
  574.  
  575.         /* if there is no client clip, we can get by with
  576.            just keeping the pointer we got, and remembering
  577.            whether or not should destroy (or maybe re-use)
  578.            it later.  this way, we avoid unnecessary copying
  579.            of regions.  (this wins especially if many clients clip
  580.            by children and have no client clip.)
  581.         */
  582.         if (pGC->clientClipType == CT_NONE)
  583.         {
  584.             if(freeCompClip) 
  585.             (*pScreen->RegionDestroy) (devPriv->pCompositeClip);
  586.             devPriv->pCompositeClip = pregWin;
  587.             devPriv->freeCompClip = freeTmpClip;
  588.         }
  589.         else
  590.         {
  591.         /* we need one 'real' region to put into the composite
  592.            clip.
  593.             if pregWin and the current composite clip 
  594.            are real, we can get rid of one.
  595.             if the current composite clip is real and
  596.            pregWin isn't, intersect the client clip and
  597.            pregWin into the existing composite clip.
  598.             if pregWin is real and the current composite
  599.            clip isn't, intersect pregWin with the client clip
  600.            and replace the composite clip with it.
  601.             if neither is real, create a new region and
  602.            do the intersection into it.
  603.         */
  604.  
  605.         (*pScreen->TranslateRegion)(pGC->clientClip,
  606.                         pDrawable->x + pGC->clipOrg.x,
  607.                         pDrawable->y + pGC->clipOrg.y);
  608.                           
  609.         if (freeCompClip)
  610.         {
  611.             (*pScreen->Intersect)(devPriv->pCompositeClip,
  612.                       pregWin, pGC->clientClip);
  613.             if (freeTmpClip)
  614.             (*pScreen->RegionDestroy)(pregWin);
  615.         }
  616.         else if (freeTmpClip)
  617.         {
  618.             (*pScreen->Intersect)(pregWin, pregWin, pGC->clientClip);
  619.             devPriv->pCompositeClip = pregWin;
  620.         }
  621.         else
  622.         {
  623.             devPriv->pCompositeClip = (*pScreen->RegionCreate)(NullBox,
  624.                                        0);
  625.             (*pScreen->Intersect)(devPriv->pCompositeClip,
  626.                       pregWin, pGC->clientClip);
  627.         }
  628.         devPriv->freeCompClip = TRUE;
  629.         (*pScreen->TranslateRegion)(pGC->clientClip,
  630.                         -(pDrawable->x + pGC->clipOrg.x),
  631.                         -(pDrawable->y + pGC->clipOrg.y));
  632.                           
  633.         }
  634.     } /* end of composite clip for a window */
  635.     else
  636.     {
  637.         BoxRec pixbounds;
  638.  
  639.         /* XXX should we translate by drawable.x/y here ? */
  640.         pixbounds.x1 = 0;
  641.         pixbounds.y1 = 0;
  642.         pixbounds.x2 = pDrawable->width;
  643.         pixbounds.y2 = pDrawable->height;
  644.  
  645.         if (devPriv->freeCompClip)
  646.             (*pScreen->RegionReset)(devPriv->pCompositeClip, &pixbounds);
  647.         else
  648.         {
  649.         devPriv->freeCompClip = TRUE;
  650.         devPriv->pCompositeClip = (*pScreen->RegionCreate)(&pixbounds,
  651.                                    1);
  652.         }
  653.  
  654.         if (pGC->clientClipType == CT_REGION)
  655.         {
  656.         (*pScreen->TranslateRegion)(devPriv->pCompositeClip,
  657.                         -pGC->clipOrg.x, -pGC->clipOrg.y);
  658.         (*pScreen->Intersect)(devPriv->pCompositeClip,
  659.                       devPriv->pCompositeClip,
  660.                       pGC->clientClip);
  661.         (*pScreen->TranslateRegion)(devPriv->pCompositeClip,
  662.                         pGC->clipOrg.x, pGC->clipOrg.y);
  663.         }
  664.     } /* end of composite clip for pixmap */
  665.     }
  666.  
  667.     new_rrop = FALSE;
  668.     new_line = FALSE;
  669.     new_text = FALSE;
  670.     new_fill = FALSE;
  671.  
  672.     mask = changes;
  673.     while (mask)
  674.     {
  675.     index = lowbit (mask);
  676.     mask &= ~index;
  677.  
  678.     /* this switch acculmulates a list of which procedures
  679.        might have to change due to changes in the GC.  in
  680.        some cases (e.g. changing one 16 bit tile for another)
  681.        we might not really need a change, but the code is
  682.        being paranoid.
  683.        this sort of batching wins if, for example, the alu
  684.        and the font have been changed, or any other pair
  685.        of items that both change the same thing.
  686.     */
  687.     switch (index)
  688.     {
  689.       case GCFunction:
  690.       case GCForeground:
  691.         new_rrop = TRUE;
  692.         break;
  693.       case GCPlaneMask:
  694.         break;
  695.       case GCBackground:
  696.         new_rrop = TRUE;    /* for opaque stipples */
  697.         break;
  698.       case GCLineStyle:
  699.       case GCLineWidth:
  700.       case GCJoinStyle:
  701.         new_line = TRUE;
  702.         break;
  703.       case GCCapStyle:
  704.         break;
  705.       case GCFillStyle:
  706.         new_fill = TRUE;
  707.         break;
  708.       case GCFillRule:
  709.         break;
  710.       case GCTile:
  711.         if(pGC->tileIsPixel)
  712.         break;
  713.         new_rotate = TRUE;
  714.         new_fill = TRUE;
  715.         break;
  716.  
  717.       case GCStipple:
  718.         if(pGC->stipple == (PixmapPtr)NULL)
  719.         break;
  720.         new_rotate = TRUE;
  721.         new_fill = TRUE;
  722.         break;
  723.  
  724.       case GCTileStipXOrigin:
  725.         new_rotate = TRUE;
  726.         break;
  727.  
  728.       case GCTileStipYOrigin:
  729.         new_rotate = TRUE;
  730.         break;
  731.  
  732.       case GCFont:
  733.         new_text = TRUE;
  734.         break;
  735.       case GCSubwindowMode:
  736.         break;
  737.       case GCGraphicsExposures:
  738.         break;
  739.       case GCClipXOrigin:
  740.         break;
  741.       case GCClipYOrigin:
  742.         break;
  743.       case GCClipMask:
  744.         break;
  745.       case GCDashOffset:
  746.         break;
  747.       case GCDashList:
  748.         break;
  749.       case GCArcMode:
  750.         break;
  751.       default:
  752.         break;
  753.     }
  754.     }
  755.  
  756.     /* deal with the changes we've collected .
  757.        new_rrop must be done first because subsequent things
  758.        depend on it.
  759.     */
  760.  
  761.     if(new_rotate || new_fill)
  762.     {
  763.     Bool new_pix = FALSE;
  764.  
  765.     /* figure out how much to rotate */
  766.     xrot = pGC->patOrg.x;
  767.     yrot = pGC->patOrg.y;
  768.     xrot += pDrawable->x;
  769.     yrot += pDrawable->y;
  770.  
  771.     switch (pGC->fillStyle)
  772.     {
  773.     case FillTiled:
  774.         /* copy current tile and stipple */
  775.         if (!pGC->tileIsPixel && (pGC->tile.pixmap->drawable.width <= 32) &&
  776.             !(pGC->tile.pixmap->drawable.width & (pGC->tile.pixmap->drawable.width - 1)))
  777.         {
  778.         mfbCopyRotatePixmap(pGC->tile.pixmap,
  779.                     &devPriv->pRotatedPixmap, xrot, yrot);
  780.         new_pix = TRUE;
  781.         }
  782.         break;
  783.     case FillStippled:
  784.     case FillOpaqueStippled:
  785.         if (pGC->stipple && (pGC->stipple->drawable.width <= 32) &&
  786.             !(pGC->stipple->drawable.width & (pGC->stipple->drawable.width - 1)))
  787.         {
  788.             if (pGC->stipple == pGC->pScreen->PixmapPerDepth[0])
  789.             {
  790.             if (pGC->stipple->drawable.width != 32)
  791.             mfbPadPixmap(pGC->stipple);
  792.             if (devPriv->pRotatedPixmap)
  793.             mfbDestroyPixmap(devPriv->pRotatedPixmap);
  794.             devPriv->pRotatedPixmap = pGC->stipple;
  795.             ++devPriv->pRotatedPixmap->refcnt;
  796.             }
  797.             else
  798.             {
  799.             mfbCopyRotatePixmap(pGC->stipple,
  800.                     &devPriv->pRotatedPixmap, xrot, yrot);
  801.             }
  802.         new_pix = TRUE;
  803.         }
  804.     }
  805.     /* destroy any previously rotated tile or stipple */
  806.     if (!new_pix && devPriv->pRotatedPixmap)
  807.     {
  808.         mfbDestroyPixmap(devPriv->pRotatedPixmap);
  809.         devPriv->pRotatedPixmap = (PixmapPtr)NULL;
  810.     }
  811.     }
  812.  
  813.     /*
  814.      * duck out here when the GC is unchanged
  815.      */
  816.  
  817.     if (!changes)
  818.     return;
  819.  
  820.     if (new_rrop || new_fill)
  821.     {
  822.     rrop = mfbReduceRop(pGC->alu, pGC->fgPixel);
  823.     devPriv->rop = rrop;
  824.     new_fill = TRUE;
  825.     /* FillArea raster op is GC's for tile filling,
  826.        and the reduced rop for solid and stipple
  827.     */
  828.     if (pGC->fillStyle == FillTiled)
  829.         devPriv->ropFillArea = pGC->alu;
  830.     else
  831.         devPriv->ropFillArea = rrop;
  832.  
  833.     /* opaque stipples:
  834.        fg    bg    ropOpStip    fill style
  835.        1    0    alu        tile
  836.        0    1    inverseAlu    tile
  837.        1    1    rrop(fg, alu)    solid
  838.        0    0    rrop(fg, alu)    solid
  839.     Note that rrop(fg, alu) == mfbPrivGC.rop, so we don't really need to
  840.     compute it.
  841.     */
  842.         if (pGC->fillStyle == FillOpaqueStippled)
  843.         {
  844.         if (pGC->fgPixel != pGC->bgPixel)
  845.         {
  846.             if (pGC->fgPixel)
  847.             devPriv->ropOpStip = pGC->alu;
  848.             else
  849.             devPriv->ropOpStip = InverseAlu[pGC->alu];
  850.         }
  851.         else
  852.             devPriv->ropOpStip = rrop;
  853.         devPriv->ropFillArea = devPriv->ropOpStip;
  854.         }
  855.     }
  856.     else
  857.     rrop = devPriv->rop;
  858.  
  859.     if (new_line || new_fill || new_text)
  860.     {
  861.     GCOps    *newops;
  862.  
  863.     if (newops = matchCommon (pGC))
  864.      {
  865.         if (pGC->ops->devPrivate.val)
  866.         mfbDestroyOps (pGC->ops);
  867.         pGC->ops = newops;
  868.         new_line = new_fill = new_text = 0;
  869.     }
  870.      else
  871.      {
  872.         if (!pGC->ops->devPrivate.val)
  873.          {
  874.         pGC->ops = mfbCreateOps (pGC->ops);
  875.         pGC->ops->devPrivate.val = 1;
  876.         }
  877.     }
  878.     }
  879.  
  880.     if (new_line || new_fill)
  881.     {
  882.     if (pGC->lineWidth == 0)
  883.     {
  884.         if ((pGC->lineStyle == LineSolid) && (pGC->fillStyle == FillSolid)
  885.         && ((rrop == RROP_WHITE) || (rrop == RROP_BLACK)))
  886.         pGC->ops->PolyArc = mfbZeroPolyArcSS;
  887.         else
  888.         pGC->ops->PolyArc = miZeroPolyArc;
  889.     }
  890.     else
  891.         pGC->ops->PolyArc = miPolyArc;
  892.     if (pGC->lineStyle == LineSolid)
  893.     {
  894.         if(pGC->lineWidth == 0)
  895.         {
  896.             if (pGC->fillStyle == FillSolid)
  897.         {
  898.             pGC->ops->PolySegment = mfbSegmentSS;
  899.             pGC->ops->Polylines = mfbLineSS;
  900.             }
  901.          else
  902.         {
  903.             pGC->ops->PolySegment = miPolySegment;
  904.             pGC->ops->Polylines = miZeroLine;
  905.         }
  906.         }
  907.         else
  908.         {
  909.         pGC->ops->PolySegment = miPolySegment;
  910.         pGC->ops->Polylines = miWideLine;
  911.         }
  912.     }
  913.     else
  914.     {
  915.         if(pGC->lineWidth == 0 && pGC->fillStyle == FillSolid)
  916.         {
  917.             pGC->ops->Polylines = mfbLineSD;
  918.         pGC->ops->PolySegment = mfbSegmentSD;
  919.         }
  920.         else
  921.         {
  922.             pGC->ops->Polylines = miWideDash;
  923.         pGC->ops->PolySegment = miPolySegment;
  924.         }
  925.     }
  926.     }
  927.  
  928.     if (new_text || new_fill)
  929.     {
  930.     if ((pGC->font) &&
  931.         (pGC->font->pFI->maxbounds.metrics.rightSideBearing -
  932.          pGC->font->pFI->minbounds.metrics.leftSideBearing) > 32)
  933.     {
  934.         pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
  935.         pGC->ops->ImageGlyphBlt = miImageGlyphBlt;
  936.     }
  937.     else
  938.     {
  939.         /* special case ImageGlyphBlt for terminal emulator fonts */
  940.         if ((pGC->font) &&
  941.         (pGC->font->pFI->terminalFont) &&
  942.         (pGC->fgPixel != pGC->bgPixel))
  943.         {
  944.         /* pcc bug makes this not compile...
  945.         pGC->ops->ImageGlyphBlt = (pGC->fgPixel) ? mfbTEGlyphBltWhite :
  946.                               mfbTEGlyphBltBlack;
  947.         */
  948.         if (pGC->fgPixel)
  949.             pGC->ops->ImageGlyphBlt = mfbTEGlyphBltWhite;
  950.         else
  951.             pGC->ops->ImageGlyphBlt = mfbTEGlyphBltBlack;
  952.         }
  953.         else
  954.         {
  955.             if (pGC->fgPixel == 0)
  956.             pGC->ops->ImageGlyphBlt = mfbImageGlyphBltBlack;
  957.             else
  958.             pGC->ops->ImageGlyphBlt = mfbImageGlyphBltWhite;
  959.         }
  960.  
  961.         /* now do PolyGlyphBlt */
  962.         if (pGC->fillStyle == FillSolid ||
  963.         (pGC->fillStyle == FillOpaqueStippled &&
  964.          pGC->fgPixel == pGC->bgPixel
  965.         )
  966.            )
  967.         {
  968.         if (rrop == RROP_WHITE)
  969.             pGC->ops->PolyGlyphBlt = mfbPolyGlyphBltWhite;
  970.         else if (rrop == RROP_BLACK)
  971.             pGC->ops->PolyGlyphBlt = mfbPolyGlyphBltBlack;
  972.         else if (rrop == RROP_INVERT)
  973.             pGC->ops->PolyGlyphBlt = mfbPolyGlyphBltInvert;
  974.         else
  975.             pGC->ops->PolyGlyphBlt = NoopDDA;
  976.         }
  977.         else
  978.         {
  979.         pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;
  980.         }
  981.     }
  982.     }
  983.  
  984.     if (new_fill)
  985.     {
  986.     /* install a suitable fillspans and pushpixels */
  987.     pGC->ops->PushPixels = mfbPushPixels;
  988.     if ((pGC->fillStyle == FillSolid) ||
  989.         ((pGC->fillStyle == FillOpaqueStippled) &&
  990.          (pGC->fgPixel == pGC->bgPixel)))
  991.     {
  992.         pGC->ops->PushPixels = mfbSolidPP;
  993.         switch(devPriv->rop)
  994.         {
  995.           case RROP_WHITE:
  996.         pGC->ops->FillSpans = mfbWhiteSolidFS;
  997.         break;
  998.           case RROP_BLACK:
  999.         pGC->ops->FillSpans = mfbBlackSolidFS;
  1000.         break;
  1001.           case RROP_INVERT:
  1002.         pGC->ops->FillSpans = mfbInvertSolidFS;
  1003.         break;
  1004.           case RROP_NOP:
  1005.         pGC->ops->FillSpans = NoopDDA;
  1006.         break;
  1007.         }
  1008.     }
  1009.     /* beyond this point, opaqueStippled ==> fg != bg */
  1010.     else if (((pGC->fillStyle == FillTiled) ||
  1011.           (pGC->fillStyle == FillOpaqueStippled)) &&
  1012.          !devPriv->pRotatedPixmap)
  1013.     {
  1014.         pGC->ops->FillSpans = mfbUnnaturalTileFS;
  1015.     }
  1016.     else if ((pGC->fillStyle == FillStippled) && !devPriv->pRotatedPixmap)
  1017.     {
  1018.         pGC->ops->FillSpans = mfbUnnaturalStippleFS;
  1019.     }
  1020.     else if (pGC->fillStyle == FillStippled)
  1021.     {
  1022.         switch(devPriv->rop)
  1023.         {
  1024.           case RROP_WHITE:
  1025.         pGC->ops->FillSpans = mfbWhiteStippleFS;
  1026.         break;
  1027.           case RROP_BLACK:
  1028.         pGC->ops->FillSpans = mfbBlackStippleFS;
  1029.         break;
  1030.           case RROP_INVERT:
  1031.         pGC->ops->FillSpans = mfbInvertStippleFS;
  1032.         break;
  1033.           case RROP_NOP:
  1034.         pGC->ops->FillSpans = NoopDDA;
  1035.         break;
  1036.         }
  1037.     }
  1038.     else /* overload tiles to do parti-colored opaque stipples */
  1039.     {
  1040.         pGC->ops->FillSpans = mfbTileFS;
  1041.     }
  1042.     if (pGC->fillStyle == FillSolid)
  1043.         pGC->ops->PolyFillArc = mfbPolyFillArcSolid;
  1044.     else
  1045.         pGC->ops->PolyFillArc = miPolyFillArc;
  1046.     /* the rectangle code doesn't deal with opaque stipples that
  1047.        are two colors -- we can fool it for fg==bg, though
  1048.      */
  1049.     if ((((pGC->fillStyle == FillTiled) ||
  1050.           (pGC->fillStyle == FillStippled)) &&
  1051.          !devPriv->pRotatedPixmap) ||
  1052.         ((pGC->fillStyle == FillOpaqueStippled) &&
  1053.          (pGC->fgPixel != pGC->bgPixel))
  1054.        )
  1055.     {
  1056.         pGC->ops->PolyFillRect = miPolyFillRect;
  1057.     }
  1058.     else /* deal with solids and natural stipples and tiles */
  1059.     {
  1060.         pGC->ops->PolyFillRect = mfbPolyFillRect;
  1061.  
  1062.         if ((pGC->fillStyle == FillSolid) ||
  1063.         ((pGC->fillStyle == FillOpaqueStippled) &&
  1064.          (pGC->fgPixel == pGC->bgPixel)))
  1065.         {
  1066.         switch(devPriv->rop)
  1067.         {
  1068.           case RROP_WHITE:
  1069.             devPriv->FillArea = mfbSolidWhiteArea;
  1070.             break;
  1071.           case RROP_BLACK:
  1072.             devPriv->FillArea = mfbSolidBlackArea;
  1073.             break;
  1074.           case RROP_INVERT:
  1075.             devPriv->FillArea = mfbSolidInvertArea;
  1076.             break;
  1077.           case RROP_NOP:
  1078.             devPriv->FillArea = NoopDDA;
  1079.             break;
  1080.         }
  1081.         }
  1082.         else if (pGC->fillStyle == FillStippled)
  1083.         {
  1084.         switch(devPriv->rop)
  1085.         {
  1086.           case RROP_WHITE:
  1087.             devPriv->FillArea = mfbStippleWhiteArea;
  1088.             break;
  1089.           case RROP_BLACK:
  1090.             devPriv->FillArea = mfbStippleBlackArea;
  1091.             break;
  1092.           case RROP_INVERT:
  1093.             devPriv->FillArea = mfbStippleInvertArea;
  1094.             break;
  1095.           case RROP_NOP:
  1096.             devPriv->FillArea = NoopDDA;
  1097.             break;
  1098.         }
  1099.         }
  1100.         else /* deal with tiles */
  1101.         {
  1102.         devPriv->FillArea = mfbTileArea32;
  1103.         }
  1104.     } /* end of natural rectangles */
  1105.     } /* end of new_fill */
  1106. }
  1107.  
  1108. /* table to map alu(src, dst) to alu(~src, dst) */
  1109. int InverseAlu[16] = {
  1110.     GXclear,
  1111.     GXandInverted,
  1112.     GXnor,
  1113.     GXcopyInverted,
  1114.     GXand,
  1115.     GXnoop,
  1116.     GXequiv,
  1117.     GXorInverted,
  1118.     GXandReverse,
  1119.     GXxor,
  1120.     GXinvert,
  1121.     GXnand,
  1122.     GXcopy,
  1123.     GXor,
  1124.     GXorReverse,
  1125.     GXset
  1126. };
  1127.  
  1128. int
  1129. mfbReduceRop(alu, src)
  1130.     register unsigned char alu;
  1131.     register Pixel src;
  1132. {
  1133.     int rop;
  1134.     if (src == 0)    /* src is black */
  1135.     {
  1136.     switch(alu)
  1137.     {
  1138.       case GXclear:
  1139.         rop = RROP_BLACK;
  1140.         break;
  1141.       case GXand:
  1142.         rop = RROP_BLACK;
  1143.         break;
  1144.       case GXandReverse:
  1145.         rop = RROP_BLACK;
  1146.         break;
  1147.       case GXcopy:
  1148.         rop = RROP_BLACK;
  1149.         break;
  1150.       case GXandInverted:
  1151.         rop = RROP_NOP;
  1152.         break;
  1153.       case GXnoop:
  1154.         rop = RROP_NOP;
  1155.         break;
  1156.       case GXxor:
  1157.         rop = RROP_NOP;
  1158.         break;
  1159.       case GXor:
  1160.         rop = RROP_NOP;
  1161.         break;
  1162.       case GXnor:
  1163.         rop = RROP_INVERT;
  1164.         break;
  1165.       case GXequiv:
  1166.         rop = RROP_INVERT;
  1167.         break;
  1168.       case GXinvert:
  1169.         rop = RROP_INVERT;
  1170.         break;
  1171.       case GXorReverse:
  1172.         rop = RROP_INVERT;
  1173.         break;
  1174.       case GXcopyInverted:
  1175.         rop = RROP_WHITE;
  1176.         break;
  1177.       case GXorInverted:
  1178.         rop = RROP_WHITE;
  1179.         break;
  1180.       case GXnand:
  1181.         rop = RROP_WHITE;
  1182.         break;
  1183.       case GXset:
  1184.         rop = RROP_WHITE;
  1185.         break;
  1186.     }
  1187.     }
  1188.     else /* src is white */
  1189.     {
  1190.     switch(alu)
  1191.     {
  1192.       case GXclear:
  1193.         rop = RROP_BLACK;
  1194.         break;
  1195.       case GXand:
  1196.         rop = RROP_NOP;
  1197.         break;
  1198.       case GXandReverse:
  1199.         rop = RROP_INVERT;
  1200.         break;
  1201.       case GXcopy:
  1202.         rop = RROP_WHITE;
  1203.         break;
  1204.       case GXandInverted:
  1205.         rop = RROP_BLACK;
  1206.         break;
  1207.       case GXnoop:
  1208.         rop = RROP_NOP;
  1209.         break;
  1210.       case GXxor:
  1211.         rop = RROP_INVERT;
  1212.         break;
  1213.       case GXor:
  1214.         rop = RROP_WHITE;
  1215.         break;
  1216.       case GXnor:
  1217.         rop = RROP_BLACK;
  1218.         break;
  1219.       case GXequiv:
  1220.         rop = RROP_NOP;
  1221.         break;
  1222.       case GXinvert:
  1223.         rop = RROP_INVERT;
  1224.         break;
  1225.       case GXorReverse:
  1226.         rop = RROP_WHITE;
  1227.         break;
  1228.       case GXcopyInverted:
  1229.         rop = RROP_BLACK;
  1230.         break;
  1231.       case GXorInverted:
  1232.         rop = RROP_NOP;
  1233.         break;
  1234.       case GXnand:
  1235.         rop = RROP_INVERT;
  1236.         break;
  1237.       case GXset:
  1238.         rop = RROP_WHITE;
  1239.         break;
  1240.     }
  1241.     }
  1242.     return rop;
  1243. }
  1244.  
  1245. void
  1246. mfbDestroyClip(pGC)
  1247.     GCPtr    pGC;
  1248. {
  1249.     if(pGC->clientClipType == CT_NONE)
  1250.     return;
  1251.     else if (pGC->clientClipType == CT_PIXMAP)
  1252.     {
  1253.     mfbDestroyPixmap((PixmapPtr)(pGC->clientClip));
  1254.     }
  1255.     else
  1256.     {
  1257.     /* we know we'll never have a list of rectangles, since
  1258.        ChangeClip immediately turns them into a region 
  1259.     */
  1260.         (*pGC->pScreen->RegionDestroy)(pGC->clientClip);
  1261.     }
  1262.     pGC->clientClip = NULL;
  1263.     pGC->clientClipType = CT_NONE;
  1264. }
  1265.  
  1266. void
  1267. mfbChangeClip(pGC, type, pvalue, nrects)
  1268.     GCPtr        pGC;
  1269.     unsigned int    type;
  1270.     pointer        pvalue;
  1271.     int            nrects;
  1272. {
  1273.     mfbDestroyClip(pGC);
  1274.     if(type == CT_PIXMAP)
  1275.     {
  1276.     /* convert the pixmap to a region */
  1277.     pGC->clientClip = (pointer) (*pGC->pScreen->BitmapToRegion)((PixmapPtr)pvalue);
  1278.     /* you wouldn't do this if you were leaving the pixmap in
  1279.        rather than converting it.
  1280.     */
  1281.     (*pGC->pScreen->DestroyPixmap)(pvalue);
  1282.     }
  1283.     else if (type == CT_REGION)
  1284.     {
  1285.     /* stuff the region in the GC */
  1286.     pGC->clientClip = pvalue;
  1287.     }
  1288.     else if (type != CT_NONE)
  1289.     {
  1290.     pGC->clientClip = (pointer) (*pGC->pScreen->RectsToRegion)(nrects,
  1291.                             (xRectangle *)pvalue,
  1292.                             type);
  1293.     xfree(pvalue);
  1294.     }
  1295.     pGC->clientClipType = (type != CT_NONE && pGC->clientClip) ? CT_REGION :
  1296.         CT_NONE;
  1297.     pGC->stateChanges |= GCClipMask;
  1298. }
  1299.  
  1300. void
  1301. mfbCopyClip (pgcDst, pgcSrc)
  1302.     GCPtr pgcDst, pgcSrc;
  1303. {
  1304.     RegionPtr prgnNew;
  1305.  
  1306.     switch(pgcSrc->clientClipType)
  1307.     {
  1308.       case CT_PIXMAP:
  1309.     ((PixmapPtr) pgcSrc->clientClip)->refcnt++;
  1310.     /* Fall through !! */
  1311.       case CT_NONE:
  1312.     mfbChangeClip(pgcDst, pgcSrc->clientClipType, pgcSrc->clientClip, 0);
  1313.     break;
  1314.       case CT_REGION:
  1315.     prgnNew = (*pgcSrc->pScreen->RegionCreate)(NULL, 1);
  1316.     (*pgcSrc->pScreen->RegionCopy)(prgnNew,
  1317.                        (RegionPtr)(pgcSrc->clientClip));
  1318.     mfbChangeClip(pgcDst, CT_REGION, (pointer)prgnNew, 0);
  1319.     break;
  1320.     }
  1321. }
  1322. @
  1323.  
  1324.  
  1325. 1.1
  1326. log
  1327. @Initial revision
  1328. @
  1329. text
  1330. @d24 1
  1331. a24 1
  1332. /* $XConsortium: mfbgc.c,v 5.18 89/11/29 19:53:27 rws Exp $ */
  1333. d423 1
  1334. a423 16
  1335.     RegionPtr        pClip;
  1336.  
  1337.     if(changes & GCClipMask)
  1338.     {
  1339.     if(pGCDst->clientClipType == CT_PIXMAP)
  1340.     {
  1341.         ((PixmapPtr)pGCDst->clientClip)->refcnt++;
  1342.     }
  1343.     else if(pGCDst->clientClipType == CT_REGION)
  1344.     {
  1345.         pClip = (RegionPtr) pGCDst->clientClip;
  1346.         pGCDst->clientClip =
  1347.             (pointer)(* pGCDst->pScreen->RegionCreate)(NULL, 1);
  1348.         (* pGCDst->pScreen->RegionCopy)(pGCDst->clientClip, pClip);
  1349.     }
  1350.     }
  1351. @
  1352.